﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.IO;

using ParamSetCollection.General.Parameters.Normal;
using ParamSetCollection.General.Logs;

namespace MainController.Hardware.PLC.MEGMEET.Datas.Groups
{
   

    abstract class ParamGroup
    {
        #region============================== 变量 ====================================
        protected static string configPath = System.Environment.CurrentDirectory + "\\Config\\Param\\";


        //错误消息
        public delegate void OnErrorHandler(string msg);
        public virtual event OnErrorHandler OnError;

        //修改动作记录

        //public virtual event OnChangeMsgHandler OnChangeMsg;


        //------------数据位置信息-------------
        protected List<ushort> m_HeadAddr = new List<ushort>();
        protected List<ushort> m_Count = new List<ushort>();


        protected ushort[] data = null;

        protected string m_baseName = "";

        protected bool m_msgLock = false;
        protected string language = "";

        protected string m_configPath;

        protected List<ParameterUnit> m_paramList = new List<ParameterUnit>();
        protected Dictionary<string, ParameterUnit> m_paramDic = new Dictionary<string, ParameterUnit>();
        protected List<string> msgList = new List<string>();//消息列表
        #endregion=====================================================================


        #region============================== 属性 ====================================
        public string BaseName { get { return m_baseName; } }
        #endregion=====================================================================


        #region============================= 内部函数 =================================

        #endregion=====================================================================


        #region============================= 保护函数 =================================
        protected void EventBinding()
        {
            foreach (ParameterUnit item in m_paramList)
            {

                //item.OnValueChange += OnValueChange;


            }
        }


        //初始化参数表,
        protected void ParamListInit(Dictionary<string, string> paramDic)
        {

            //初始化code以及位置参数,初始化名称，单位
            foreach (string item in paramDic.Keys)
            {

                try
                {
                    //m_paramList.Add(new ParameterUnit(item, paramDic[item], "0"));
                    //m_paramDic.Add(item, m_paramList[m_paramList.Count - 1]);

                }
                catch (Exception)
                {


                }
            }

            //解析xml文件
            if (this.m_configPath == "" || File.Exists(this.m_configPath) == false)
            {
                return;
            }

            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.Load(m_configPath);

            XmlNode nod = xmlDoc.SelectSingleNode("ParamsList");
            if (nod != null)
            {
                XmlNodeList nodeList = nod.ChildNodes;
                for (int i = 0; i < nodeList.Count; i++)
                {
                    XmlNode _nod = nodeList[i];
                    string code = _nod.Name;


                    if (m_paramDic.ContainsKey(code))
                    {
                        XmlNodeList subList = _nod.ChildNodes;
                        for (int j = 0; j < subList.Count; j++)
                        {
                            m_paramDic[code].SetProperty(subList[j].Name, subList[j].InnerText);

                        }

                    }

                }

            }


        }

        //发出错误消息
        protected virtual void SendErrorMessage(string msg)
        {
            if (OnError != null)
            {
                OnError(msg);
            }
        }


        //修改data缓存值
        protected abstract void ChangeBuffer(string position, object value);

        #endregion====================================================================


        #region============================= 公开函数 =================================
        /// <summary>
        /// 
        /// </summary>
        /// <param name="paramType">参数的分类</param>
        /// <param name="baseCode">用作机型</param>
        /// <param name="fileName">配置文档路径</param>
        /// <param name="paramDic"></param>
        /// <param name="cfgPath"></param>
        /// <param name="dataBuf"></param>
        public ParamGroup(string paramType, string baseCode, string fileName,  Dictionary<string, string> paramDic, string cfgPath, ushort[] dataBuf)
        {

            this.m_baseName = baseCode;



            this.data = dataBuf;


            this.m_configPath = cfgPath + baseCode + "\\" + paramType + "\\"  + fileName;


            if (File.Exists(m_configPath) == false)
            {
                SendErrorMessage("config file missing: " + this.m_configPath);
                return;
            }

            ParamListInit(paramDic);
            EventBinding();

        }


        //获取写参数指令
        public abstract List<CommUnit> GetWriteDataCommands(Dictionary<string, ushort> dataList = null, List<ParameterUnit> paramList = null);


        //更新参数，用于plc参数监控
        public abstract void InputNewDatas(ushort[] data);

        //获取参数修改指令
        public abstract List<CommUnit> GetParamSetting(ref List<ParamUnit> paramList);

        //初始化系统参数
        public abstract List<CommUnit> InitCtx(object ctxData);






        ////读取参数
        //public Dictionary<string, ParamUnit> GetRemoteParam()
        //{
        //    Dictionary<string, ParamUnit> dataList = new Dictionary<string, ParamUnit>();
        //    foreach (string item in m_paramDic.Keys)
        //    {
        //        dataList.Add(m_paramDic[item].Code, new ParamUnit(m_paramDic[item].Code, m_paramDic[item].Name, m_paramDic[item].MesName, m_paramDic[item].Type, m_paramDic[item].RemoteEn, m_paramDic[item].Value, m_paramDic[item].Unit,
        //                                                m_paramDic[item].Format, m_paramDic[item].Max, m_paramDic[item].Min));
        //    }

        //    return dataList;
        //}

        public List<ParamUnit> GetRemoteDatas()
        {
            List<ParamUnit> dataBuf = new List<ParamUnit>();

            foreach (string item in m_paramDic.Keys)
            {

                dataBuf.Add(m_paramDic[item].CreateARenewParamUnit(true));

            }

            return dataBuf;
        }

        public List<ParamUnit> GetParamList()
        {
            List<ParamUnit> buf = new List<ParamUnit>();
            foreach (string item in m_paramDic.Keys)
            {
                buf.Add(m_paramDic[item].CreateARenewParamUnit());
            }

            return buf;
        }

        //获取初始化指令
        public abstract List<CommUnit> GetInitCmdList();


        public virtual bool InitUIParam(ParamUnit pu)
        {
            string[] str = pu.Code.Split('.');//JTR.SV.PARAM
            if (m_paramDic.ContainsKey(str[2]))
            {
                //pu.Format = m_paramDic[str[2]].Format;
                //if (pu.MaxLock == false)
                //    pu.Max = m_paramDic[str[2]].Max;
                //pu.Min = m_paramDic[str[2]].Min;
                //pu.MesName = m_paramDic[str[2]].MesName;

                //pu.RemoteEnable = m_paramDic[str[2]].RemoteEnable;
                //pu.LogEnable = m_paramDic[str[2]].LogEnable;

                //foreach (var key in m_paramDic[str[2]].Names.Keys)
                //{
                //    pu.Names.Add(key, m_paramDic[str[2]].Names[key]);
                //}
          
                //pu.Unit = m_paramDic[str[2]].Unit;
                //pu.Value = m_paramDic[str[2]].Value;


                //m_paramDic[str[2]].ShortUpdateList.Add(pu);

                return true;
            }

            return false;
        }



        public void ReduceParamRange(ParamUnit pu)
        {
            string[] str = pu.Code.Split('.');
            if (m_paramDic.ContainsKey(str[2]))
            {
                //m_paramDic[str[2]].Max = pu.m_max;
                //m_paramDic[str[2]].Min = pu.m_min;
            }
        }
        #endregion====================================================================


        #region============================= 消息响应 ================================
        protected void OnValueChange(ParamRenewLogMsgUnit logUnit)
        {
            if (m_msgLock == true)
            {
                return;
            }

            //this.OnChangeMsg?.Invoke(logUnit);

        }
        #endregion====================================================================
    }
}
